# 版本: 1.0.0
# 作者: 陈振玺
# 功能: 数据可视化工具，支持CSV/XLSX文件读取并生成基于Plotly的交互式网页

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.offline as pyo
import argparse
import sys
from pathlib import Path
import json

class DataVisualizer:
    """
    数据可视化工具类
    支持多种图表类型和交互式网页生成
    
    版本: 1.0.0
    作者: 陈振玺
    """
    
    def __init__(self):
        self.data = None
        self.numeric_columns = []
        self.categorical_columns = []
        
    def load_data(self, file_path):
        """
        加载CSV或XLSX文件
        
        Args:
            file_path (str): 文件路径
            
        Returns:
            bool: 加载成功返回True，否则返回False
        """
        try:
            file_path = Path(file_path)
            
            if not file_path.exists():
                print(f"错误: 文件 '{file_path}' 不存在")
                return False
                
            # 根据文件扩展名选择读取方法
            if file_path.suffix.lower() == '.xlsx':
                self.data = pd.read_excel(file_path)
            elif file_path.suffix.lower() in ['.csv', '.tsv']:
                # 自动检测分隔符
                delimiter = '\t' if file_path.suffix.lower() == '.tsv' else ','
                self.data = pd.read_csv(file_path, delimiter=delimiter)
            else:
                print(f"错误: 不支持的文件格式 '{file_path.suffix}'")
                return False
                
            # 分析列类型
            self._analyze_columns()
            print(f"成功加载数据: {len(self.data)} 行, {len(self.data.columns)} 列")
            return True
            
        except Exception as e:
            print(f"加载文件时出错: {str(e)}")
            return False
    
    def _analyze_columns(self):
        """
        分析数据列类型
        """
        self.numeric_columns = []
        self.categorical_columns = []
        
        for col in self.data.columns:
            if pd.api.types.is_numeric_dtype(self.data[col]):
                self.numeric_columns.append(col)
            else:
                self.categorical_columns.append(col)
    
    def create_boxplot(self, x_col=None, y_col=None, color_col=None):
        """
        创建箱线图
        
        Args:
            x_col (str): X轴列名
            y_col (str): Y轴列名（必须是数值型）
            color_col (str): 颜色分组列名
            
        Returns:
            plotly.graph_objects.Figure: 图表对象
        """
        if self.data is None:
            raise ValueError("请先加载数据")
            
        # 验证Y轴必须是数值型
        if y_col and y_col not in self.numeric_columns:
            raise ValueError(f"Y轴列 '{y_col}' 必须是数值型。可用的数值型列: {self.numeric_columns}")
        
        # 创建箱线图
        fig = px.box(
            self.data,
            x=x_col,
            y=y_col,
            color=color_col,
            title=f"箱线图: {y_col or 'Y轴'} vs {x_col or 'X轴'}"
        )
        
        # 优化布局
        fig.update_layout(
            xaxis_title=x_col or "X轴",
            yaxis_title=y_col or "Y轴",
            showlegend=bool(color_col),
            height=600
        )
        
        return fig
    
    def create_scatter(self, x_col, y_col, color_col=None, size_col=None):
        """
        创建散点图
        
        Args:
            x_col (str): X轴列名
            y_col (str): Y轴列名
            color_col (str): 颜色分组列名
            size_col (str): 点大小列名
            
        Returns:
            plotly.graph_objects.Figure: 图表对象
        """
        if self.data is None:
            raise ValueError("请先加载数据")
            
        fig = px.scatter(
            self.data,
            x=x_col,
            y=y_col,
            color=color_col,
            size=size_col,
            title=f"散点图: {y_col} vs {x_col}",
            hover_data=self.data.columns.tolist()
        )
        
        fig.update_layout(
            xaxis_title=x_col,
            yaxis_title=y_col,
            height=600
        )
        
        return fig
    
    def create_line(self, x_col, y_col, color_col=None):
        """
        创建线图
        
        Args:
            x_col (str): X轴列名
            y_col (str): Y轴列名
            color_col (str): 颜色分组列名
            
        Returns:
            plotly.graph_objects.Figure: 图表对象
        """
        if self.data is None:
            raise ValueError("请先加载数据")
            
        fig = px.line(
            self.data,
            x=x_col,
            y=y_col,
            color=color_col,
            title=f"线图: {y_col} vs {x_col}"
        )
        
        fig.update_layout(
            xaxis_title=x_col,
            yaxis_title=y_col,
            height=600
        )
        
        return fig
    
    def create_bar(self, x_col, y_col, color_col=None):
        """
        创建柱状图
        
        Args:
            x_col (str): X轴列名
            y_col (str): Y轴列名
            color_col (str): 颜色分组列名
            
        Returns:
            plotly.graph_objects.Figure: 图表对象
        """
        if self.data is None:
            raise ValueError("请先加载数据")
            
        fig = px.bar(
            self.data,
            x=x_col,
            y=y_col,
            color=color_col,
            title=f"柱状图: {y_col} vs {x_col}"
        )
        
        fig.update_layout(
            xaxis_title=x_col,
            yaxis_title=y_col,
            height=600
        )
        
        return fig
    
    def create_histogram(self, x_col, color_col=None):
        """
        创建直方图
        
        Args:
            x_col (str): X轴列名
            color_col (str): 颜色分组列名
            
        Returns:
            plotly.graph_objects.Figure: 图表对象
        """
        if self.data is None:
            raise ValueError("请先加载数据")
            
        fig = px.histogram(
            self.data,
            x=x_col,
            color=color_col,
            title=f"直方图: {x_col}"
        )
        
        fig.update_layout(
            xaxis_title=x_col,
            yaxis_title="频次",
            height=600
        )
        
        return fig
    
    def create_stacked_bar(self, x_col, y_col, color_col, percentage=False):
        """
        创建堆叠柱状图
        
        Args:
            x_col (str): X轴列名
            y_col (str): Y轴列名（数值型）
            color_col (str): 堆叠分组列名
            percentage (bool): 是否显示为百分比占比
            
        Returns:
            plotly.graph_objects.Figure: 图表对象
        """
        if self.data is None:
            raise ValueError("请先加载数据")
            
        if not x_col or not y_col or not color_col:
            raise ValueError("堆叠柱状图需要指定X轴、Y轴和堆叠分组列")
            
        # 验证Y轴必须是数值型
        if y_col not in self.numeric_columns:
            raise ValueError(f"Y轴列 '{y_col}' 必须是数值型。可用的数值型列: {self.numeric_columns}")
        
        # 根据是否显示百分比来处理数据
        if percentage:
            # 计算每个X轴分组内的百分比
            data_copy = self.data.copy()
            # 按X轴分组计算总和
            group_totals = data_copy.groupby(x_col)[y_col].sum().reset_index()
            group_totals.columns = [x_col, 'total']
            # 合并总和数据
            data_copy = data_copy.merge(group_totals, on=x_col)
            # 计算百分比
            data_copy['percentage'] = (data_copy[y_col] / data_copy['total']) * 100
            
            fig = px.bar(
                data_copy,
                x=x_col,
                y='percentage',
                color=color_col,
                title=f"堆叠柱状图（百分比）: {y_col} vs {x_col} (按 {color_col} 堆叠)"
            )
            
            # 设置Y轴标题为百分比
            yaxis_title = f"{y_col} (%)"
        else:
            fig = px.bar(
                self.data,
                x=x_col,
                y=y_col,
                color=color_col,
                title=f"堆叠柱状图（数值）: {y_col} vs {x_col} (按 {color_col} 堆叠)"
            )
            yaxis_title = y_col
        
        # 设置为堆叠模式
        fig.update_layout(
            barmode='stack',
            xaxis_title=x_col,
            yaxis_title=yaxis_title,
            height=600
        )
        
        return fig
    
    def create_data_table(self):
        """
        创建数据表格
        
        Returns:
            str: HTML表格字符串
        """
        if self.data is None:
            raise ValueError("请先加载数据")
            
        # 创建带滚动条的表格HTML
        table_html = f"""
        <div style="max-height: 400px; overflow-y: auto; border: 1px solid #ddd; margin: 20px 0;">
            <h3>数据表格 ({len(self.data)} 行 × {len(self.data.columns)} 列)</h3>
            {self.data.to_html(classes='table table-striped table-hover', table_id='data-table', escape=False, max_rows=1000)}
        </div>
        """
        
        return table_html
    
    def generate_interactive_html(self, output_file, title="数据可视化工具"):
        """
        生成交互式HTML网页，允许用户在网页中选择图表类型和参数
        
        Args:
            output_file (str): 输出文件路径
            
        Returns:
            bool: 生成成功返回True，否则返回False
        """
        if self.data is None:
            print("错误: 请先加载数据")
            return False
            
        try:
            # 生成数据表格HTML
            table_html = self.create_data_table()
            
            # 将数据转换为JSON格式供JavaScript使用
            data_json = self.data.to_json(orient='records')
            columns_info = {
                'all_columns': self.data.columns.tolist(),
                'numeric_columns': self.numeric_columns,
                'categorical_columns': self.categorical_columns
            }
            
            # 生成完整HTML页面
            full_html = f"""
            <!DOCTYPE html>
            <html lang="zh-CN">
            <head>
                <meta charset="UTF-8">
                <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <title>{title}</title>
                <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
                <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
                <style>
                    body {{ font-family: 'Arial', sans-serif; margin: 20px; }}
                    .container {{ max-width: 1400px; }}
                    .control-panel {{ background-color: #f8f9fa; padding: 20px; border-radius: 5px; margin: 20px 0; }}
                    .chart-container {{ margin: 20px 0; min-height: 600px; }}
                    .info-panel {{ background-color: #e9ecef; padding: 15px; border-radius: 5px; margin: 20px 0; }}
                    #data-table {{ font-size: 12px; }}
                    #data-table th {{ background-color: #007bff; color: white; position: sticky; top: 0; }}
                    .form-select, .btn {{ margin: 5px; }}
                    #chart-div {{ border: 1px solid #ddd; border-radius: 5px; padding: 10px; }}
                </style>
            </head>
            <body>
                <div class="container">
                    <h1 class="text-center mb-4">{title}</h1>
                    
                    <div class="info-panel">
                        <h4>数据信息</h4>
                        <div class="row">
                            <div class="col-md-3">
                                <p><strong>数据维度:</strong> {self.data.shape[0]} 行 × {self.data.shape[1]} 列</p>
                            </div>
                            <div class="col-md-4">
                                <p><strong>数值型列:</strong> {', '.join(self.numeric_columns) if self.numeric_columns else '无'}</p>
                            </div>
                            <div class="col-md-5">
                                <p><strong>分类型列:</strong> {', '.join(self.categorical_columns) if self.categorical_columns else '无'}</p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="control-panel">
                        <h4>图表配置</h4>
                        <div class="row">
                            <div class="col-md-2">
                                <label for="chart-type" class="form-label">图表类型:</label>
                                <select id="chart-type" class="form-select">
                                    <option value="boxplot">箱线图</option>
                                    <option value="scatter">散点图</option>
                                    <option value="line">线图</option>
                                    <option value="bar">柱状图</option>
                                    <option value="stacked_bar">堆叠柱状图</option>
                                    <option value="histogram">直方图</option>
                                </select>
                            </div>
                            <div class="col-md-2">
                                <label for="x-axis" class="form-label">X轴:</label>
                                <select id="x-axis" class="form-select">
                                    <option value="">请选择</option>
                                </select>
                            </div>
                            <div class="col-md-2">
                                <label for="y-axis" class="form-label">Y轴:</label>
                                <select id="y-axis" class="form-select">
                                    <option value="">请选择</option>
                                </select>
                            </div>
                            <div class="col-md-2">
                                <label for="color-col" class="form-label">颜色分组:</label>
                                <select id="color-col" class="form-select">
                                    <option value="">无</option>
                                </select>
                            </div>
                            <div class="col-md-2">
                                <label for="size-col" class="form-label">点大小:</label>
                                <select id="size-col" class="form-select">
                                    <option value="">无</option>
                                </select>
                            </div>
                            <div class="col-md-2">
                                <label for="y-mode" class="form-label">Y轴模式:</label>
                                <select id="y-mode" class="form-select">
                                    <option value="value">数值</option>
                                    <option value="percentage">占比(%)</option>
                                </select>
                            </div>
                            <div class="col-md-2 d-flex align-items-end">
                                <button id="update-chart" class="btn btn-primary">更新图表</button>
                            </div>
                        </div>
                    </div>
                    
                    <div class="chart-container">
                        <div id="chart-div"></div>
                    </div>
                    
                    {table_html}
                    
                    <footer class="text-center mt-4">
                        <p class="text-muted">由 Toolbelt 数据可视化工具生成 | 版本: 1.0.0 | 作者: 陈振玺</p>
                    </footer>
                </div>
                
                <script>
                    // 数据和列信息
                    const data = {data_json};
                    const columnsInfo = {json.dumps(columns_info)};
                    
                    // 初始化页面
                    function initializePage() {{
                        populateColumnSelects();
                        updateAxisOptions(); // 根据默认图表类型更新轴选项
                        updateChart();
                        
                        // 添加图表类型变化监听器
                        document.getElementById('chart-type').addEventListener('change', function() {{
                            const chartType = this.value;
                            const sizeCol = document.getElementById('size-col');
                            // 只有散点图支持点大小
                            sizeCol.disabled = chartType !== 'scatter';
                            updateAxisOptions();
                            updateChart();
                        }});
                    }}
                    
                    // 填充列选择下拉框（初始化所有选项）
                    function populateColumnSelects() {{
                        const allColumns = columnsInfo.all_columns;
                        const numericColumns = columnsInfo.numeric_columns;
                        
                        // 颜色分组选项（所有列）
                        const colorSelect = document.getElementById('color-col');
                        colorSelect.innerHTML = '<option value="">无</option>';
                        allColumns.forEach(col => {{
                            colorSelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                        }});
                        
                        // 点大小选项（仅数值型列）
                        const sizeSelect = document.getElementById('size-col');
                        sizeSelect.innerHTML = '<option value="">无</option>';
                        numericColumns.forEach(col => {{
                            sizeSelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                        }});
                    }}
                    
                    // 根据图表类型更新轴选项
                    function updateAxisOptions() {{
                        const chartType = document.getElementById('chart-type').value;
                        const allColumns = columnsInfo.all_columns;
                        const numericColumns = columnsInfo.numeric_columns;
                        
                        const xSelect = document.getElementById('x-axis');
                        const ySelect = document.getElementById('y-axis');
                        
                        // 清空现有选项
                        xSelect.innerHTML = '<option value="">请选择</option>';
                        ySelect.innerHTML = '<option value="">请选择</option>';
                        
                        // 重新启用Y轴选择
                        ySelect.disabled = false;
                        
                        // 根据图表类型设置不同的轴选项
                        switch(chartType) {{
                            case 'boxplot':
                                // 箱线图：X轴可以是分类列，Y轴必须是数值列
                                allColumns.forEach(col => {{
                                    xSelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                                }});
                                numericColumns.forEach(col => {{
                                    ySelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                                }});
                                break;
                            case 'scatter':
                            case 'line':
                                // 散点图和线图：X轴和Y轴都可以是数值列
                                numericColumns.forEach(col => {{
                                    xSelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                                    ySelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                                }});
                                break;
                            case 'bar':
                            case 'stacked_bar':
                                // 柱状图：X轴通常是分类列，Y轴是数值列
                                allColumns.forEach(col => {{
                                    xSelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                                }});
                                numericColumns.forEach(col => {{
                                    ySelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                                }});
                                break;
                            case 'histogram':
                                // 直方图：只需要X轴，通常是数值列或分类列
                                allColumns.forEach(col => {{
                                    xSelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                                }});
                                // 直方图不需要Y轴选择
                                ySelect.innerHTML = '<option value="">自动计算频次</option>';
                                ySelect.disabled = true;
                                break;
                            default:
                                // 默认情况：所有列都可选
                                allColumns.forEach(col => {{
                                    xSelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                                    ySelect.innerHTML += '<option value="' + col + '">' + col + '</option>';
                                }});
                        }}
                    }}
                    
                    // 更新图表
                    function updateChart() {{
                        const chartType = document.getElementById('chart-type').value;
                        const xCol = document.getElementById('x-axis').value;
                        const yCol = document.getElementById('y-axis').value;
                        const colorCol = document.getElementById('color-col').value;
                        const sizeCol = document.getElementById('size-col').value;
                        const yMode = document.getElementById('y-mode').value;
                        
                        let trace = {{}};
                        let layout = {{
                            title: getChartTitle(chartType) + ": " + (yCol || "Y轴") + " vs " + (xCol || "X轴"),
                            xaxis: {{ title: xCol || "X轴" }},
                            yaxis: {{ title: yCol || "Y轴" }},
                            height: 600
                        }};
                        
                        // 根据图表类型创建trace
                        switch(chartType) {{
                            case 'boxplot':
                                if (!yCol) {{
                                    alert('箱线图需要选择Y轴（数值型列）');
                                    return;
                                }}
                                trace = {{
                                    type: 'box',
                                    x: xCol ? data.map(d => d[xCol]) : undefined,
                                    y: data.map(d => d[yCol]),
                                    name: yCol,
                                    boxpoints: 'outliers'
                                }};
                                if (colorCol && xCol) {{
                                    // 分组箱线图
                                    const groups = [...new Set(data.map(d => d[colorCol]))];
                                    const traces = groups.map(group => ({{
                                        type: 'box',
                                        x: data.filter(d => d[colorCol] === group).map(d => d[xCol]),
                                        y: data.filter(d => d[colorCol] === group).map(d => d[yCol]),
                                        name: group,
                                        boxpoints: 'outliers',
                                        offsetgroup: group
                                    }}));
                                    Plotly.newPlot('chart-div', traces, layout);
                                    return;
                                }} else if (colorCol && !xCol) {{
                                    // 按颜色分组的箱线图（无X轴分组）
                                    const groups = [...new Set(data.map(d => d[colorCol]))];
                                    const traces = groups.map(group => ({{
                                        type: 'box',
                                        y: data.filter(d => d[colorCol] === group).map(d => d[yCol]),
                                        name: group,
                                        boxpoints: 'outliers'
                                    }}));
                                    Plotly.newPlot('chart-div', traces, layout);
                                    return;
                                }}
                                break;
                                
                            case 'scatter':
                                if (!xCol || !yCol) {{
                                    alert('散点图需要选择X轴和Y轴');
                                    return;
                                }}
                                trace = {{
                                    type: 'scatter',
                                    mode: 'markers',
                                    x: data.map(d => d[xCol]),
                                    y: data.map(d => d[yCol]),
                                    marker: {{
                                        color: colorCol ? data.map(d => d[colorCol]) : undefined,
                                        size: sizeCol ? data.map(d => d[sizeCol]) : undefined,
                                        colorscale: 'Viridis'
                                    }}
                                }};
                                break;
                                
                            case 'line':
                                if (!xCol || !yCol) {{
                                    alert('线图需要选择X轴和Y轴');
                                    return;
                                }}
                                trace = {{
                                    type: 'scatter',
                                    mode: 'lines+markers',
                                    x: data.map(d => d[xCol]),
                                    y: data.map(d => d[yCol])
                                }};
                                break;
                                
                            case 'bar':
                                if (!xCol || !yCol) {{
                                    alert('柱状图需要选择X轴和Y轴');
                                    return;
                                }}
                                trace = {{
                                    type: 'bar',
                                    x: data.map(d => d[xCol]),
                                    y: data.map(d => d[yCol]),
                                    marker: {{
                                        color: colorCol ? data.map(d => d[colorCol]) : undefined,
                                        colorscale: 'Viridis'
                                    }}
                                }};
                                break;
                                
                            case 'stacked_bar':
                                if (!xCol || !yCol || !colorCol) {{
                                    alert('堆叠柱状图需要选择X轴、Y轴和颜色分组列');
                                    return;
                                }}
                                // 创建堆叠柱状图
                                const stackGroups = [...new Set(data.map(d => d[colorCol]))];
                                let stackTraces;
                                
                                if (yMode === 'percentage') {{
                                    // 计算百分比数据
                                    const xGroups = [...new Set(data.map(d => d[xCol]))];
                                    const percentageData = [];
                                    
                                    xGroups.forEach(xGroup => {{
                                        const groupData = data.filter(d => d[xCol] === xGroup);
                                        const total = groupData.reduce((sum, d) => sum + (parseFloat(d[yCol]) || 0), 0);
                                        
                                        groupData.forEach(d => {{
                                            percentageData.push({{
                                                ...d,
                                                percentage: total > 0 ? ((parseFloat(d[yCol]) || 0) / total) * 100 : 0
                                            }});
                                        }});
                                    }});
                                    
                                    stackTraces = stackGroups.map(group => ({{
                                        type: 'bar',
                                        name: group,
                                        x: percentageData.filter(d => d[colorCol] === group).map(d => d[xCol]),
                                        y: percentageData.filter(d => d[colorCol] === group).map(d => d.percentage)
                                    }}));
                                    
                                    layout.yaxis.title = yCol + ' (%)';
                                    layout.title = '堆叠柱状图（百分比）: ' + yCol + ' vs ' + xCol + ' (按 ' + colorCol + ' 堆叠)';
                                }} else {{
                                    stackTraces = stackGroups.map(group => ({{
                                        type: 'bar',
                                        name: group,
                                        x: data.filter(d => d[colorCol] === group).map(d => d[xCol]),
                                        y: data.filter(d => d[colorCol] === group).map(d => d[yCol])
                                    }}));
                                    
                                    layout.yaxis.title = yCol;
                                    layout.title = '堆叠柱状图（数值）: ' + yCol + ' vs ' + xCol + ' (按 ' + colorCol + ' 堆叠)';
                                }}
                                
                                layout.barmode = 'stack';
                                Plotly.newPlot('chart-div', stackTraces, layout);
                                return;
                                
                            case 'histogram':
                                if (!xCol) {{
                                    alert('直方图需要选择X轴');
                                    return;
                                }}
                                trace = {{
                                    type: 'histogram',
                                    x: data.map(d => d[xCol]),
                                    marker: {{
                                        color: colorCol ? data.map(d => d[colorCol]) : undefined
                                    }}
                                }};
                                layout.yaxis.title = '频次';
                                break;
                        }}
                        
                        Plotly.newPlot('chart-div', [trace], layout);
                    }}
                    
                    // 获取图表标题
                    function getChartTitle(chartType) {{
                        const titles = {{
                            'boxplot': '箱线图',
                            'scatter': '散点图',
                            'line': '线图',
                            'bar': '柱状图',
                            'stacked_bar': '堆叠柱状图',
                            'histogram': '直方图'
                        }};
                        return titles[chartType] || '图表';
                    }}
                    
                    // 事件监听
                    document.getElementById('update-chart').addEventListener('click', updateChart);
                    
                    // 页面加载完成后初始化
                    document.addEventListener('DOMContentLoaded', initializePage);
                </script>
            </body>
            </html>
            """
            
            # 写入文件
            with open(output_file, 'w', encoding='utf-8') as f:
                f.write(full_html)
                
            print(f"成功生成交互式HTML文件: {output_file}")
            return True
            
        except Exception as e:
            print(f"生成HTML时出错: {str(e)}")
            return False
    
    def get_column_info(self):
        """
        获取列信息
        
        Returns:
            dict: 列信息字典
        """
        if self.data is None:
            return {}
            
        return {
            'all_columns': self.data.columns.tolist(),
            'numeric_columns': self.numeric_columns,
            'categorical_columns': self.categorical_columns,
            'data_shape': self.data.shape
        }

def main():
    """
    命令行主函数
    
    版本: 1.0.0
    作者: 陈振玺
    """
    parser = argparse.ArgumentParser(description='数据可视化工具 - 交互式图表生成器')
    parser.add_argument('-i', '--input', required=True, help='输入文件路径 (CSV或XLSX)')
    parser.add_argument('-o', '--output', required=True, help='输出HTML文件路径')
    parser.add_argument('-t', '--title', default='数据可视化工具', help='网页标题 (默认: 数据可视化工具)')
    
    args = parser.parse_args()
    
    # 创建可视化工具实例
    visualizer = DataVisualizer()
    
    # 加载数据
    if not visualizer.load_data(args.input):
        sys.exit(1)
    
    # 生成交互式HTML
    if visualizer.generate_interactive_html(args.output, args.title):
        print(f"\n数据可视化工具已生成交互式网页: {args.output}")
        print("请在浏览器中打开该文件，然后选择图表类型和参数进行可视化。")
        return 0
    else:
        return 1

if __name__ == '__main__':
    main()